package com.xiaoma.socket

import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.coroutineScope
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.xiaoma.socket.databinding.ActivityMainBinding
import com.xiaoma.socket.databinding.ViewIpBinding
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch


class MainActivity : AppCompatActivity() {
    private val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }

    class Holder(parent: ViewGroup) : ViewHolder(
        LayoutInflater.from(parent.context)
            .inflate(R.layout.view_ip, parent, false)
    ) {
        private val binding by lazy { ViewIpBinding.bind(itemView) }
        fun refresh(address: Address) {
            binding.tvIp.text = "${address.type}: ${address.host}"
        }
    }

    class Adapter(
        lifecycle: Lifecycle,
        ipList: Flow<List<Address>>
    ) : androidx.recyclerview.widget.ListAdapter<Address, Holder>(diff) {
        companion object {
            private val diff = object : DiffUtil.ItemCallback<Address>() {
                override fun areItemsTheSame(
                    oldItem: Address,
                    newItem: Address
                ) = oldItem == newItem

                override fun areContentsTheSame(
                    oldItem: Address,
                    newItem: Address
                ) = oldItem == newItem
            }
        }

        init {
            lifecycle.apply {
                coroutineScope.launch {
                    repeatOnLifecycle(Lifecycle.State.STARTED) {
                        ipList.collect { newList ->
                            submitList(newList)
                        }
                    }
                }
            }
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
            Holder(parent)

        override fun onBindViewHolder(holder: Holder, position: Int) =
            holder.refresh(getItem(position))
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(binding.root)

        ViewCompat.setOnApplyWindowInsetsListener(binding.main) { view, insets ->
            insets.apply {
                val inset = getInsets(WindowInsetsCompat.Type.systemBars())
                view.setPadding(
                    inset.left,
                    inset.top,
                    inset.right,
                    inset.bottom
                )
            }
        }

        binding.rvList.adapter = Adapter(
            lifecycle,
            NetworkStateWatcher.ipAddresses
        )

        binding.btnRequirePermission.setOnClickListener {
            val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
            startActivityForResult(intent, 100)
        }

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.RESUMED) {
                PermissionManager.refresh()
            }
        }

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                PermissionManager.granted.collect { granted ->
                    binding.vState.visibility = View.INVISIBLE
                    binding.tvState.visibility = View.INVISIBLE
                    binding.btnRequirePermission.visibility = View.INVISIBLE
                    when (granted) {
                        true -> {
                            binding.vState.visibility = View.VISIBLE
                            binding.tvState.visibility = View.VISIBLE
                        }

                        false -> {
                            binding.btnRequirePermission.visibility = View.VISIBLE
                        }
                    }
                }
            }
        }

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                combine(
                    ForegroundService.enableState,
                    PortManager.port,
                    ::Pair
                ).collect { (enable, port) ->
                    when (enable) {
                        true -> {
                            binding.vState.isEnabled = true
                            binding.tvState.text = "服务已启动, 端口: $port"
                        }

                        false -> {
                            binding.vState.isEnabled = false
                            binding.tvState.text = "服务未启动"
                        }
                    }
                }
            }
        }
    }
}